import java.util.ArrayList;
import java.util.Collections;

public class BadugiReka 
{
	ArrayList<BadugiKarta> karty;
	BadugiUklad uklad;
	
	public BadugiReka(ArrayList<BadugiKarta> karty)
	{
		Collections.sort(karty);
		this.karty = karty;
	}
	
	public BadugiKarta wezKarte(int indeks)
	{
		return karty.get(indeks);
	}
	
	public void dodajKarte(BadugiKarta k)
	{
		if (karty.size() < 4)
		{
			karty.add(k);
		}
		Collections.sort(karty);
	}
	
	public void usunKarty(ArrayList<BadugiKarta> kartyDoUsuniecia)
	{
		karty.removeAll(kartyDoUsuniecia);
	}
	
	public String pobierzUklad()
	{
		ustalUklad();
		return uklad.name();
	}
	
	public void ustalUklad()
	{
		if (czyFourCardBadugi())
		{
			uklad = BadugiUklad.FourCardBadugi;
		}
		else if (czyThreeCardBadugi())
		{
			uklad = BadugiUklad.ThreeCardBadugi;
		}
		else if (czyPair())
		{
			uklad = BadugiUklad.Pair;
		}
		else if (czyTwoCardBadugi())
		{
			uklad = BadugiUklad.TwoCardBadugi;
		}
		else if (czyTwoPairs())
		{
			uklad = BadugiUklad.TwoPairs;
		}
		else if (czyThree())
		{
			uklad = BadugiUklad.Three;
		}
		else if (czyStreet())
		{
			uklad = BadugiUklad.Street;
		}
		else if (czyColour())
		{
			uklad = BadugiUklad.Colour;
		}
		else
		{
			uklad = BadugiUklad.LowestBadugi;
		}
	}	
	
	private boolean czyFourCardBadugi()
	{
		if (czyColour() || czyStreet() || czyThree() || czyPair())
		{
			return false;
		}
		else
		{
			return true;
		}
		
	}
	
	private boolean czyThreeCardBadugi()
	{
		if (czyColour() || czyStreet() || czyThree())
		{
			return false;
		}
		else
		{
			return true;
		}
		
	}
	
	private boolean czyPair()
	{
		 return porownajFiguryKart(0, 1) || porownajFiguryKart(1, 2) || porownajFiguryKart(2, 3);
		
	}
	
	private boolean czyTwoCardBadugi()
	{
		if (czyColour() || czyStreet())
		{
			return false;
		}
		else
		{
			return true;
		}
		
	}
	
	private boolean czyTwoPairs()
	{
		return porownajFiguryKart(0, 1) && porownajFiguryKart(2, 3);
		
	}
	
	private boolean czyThree()
	{
		return porownajFiguryKart(0, 2) || porownajFiguryKart(1, 3);
		
	}
	
	private boolean czyStreet()
	{
		ArrayList<BadugiKarta> kopiaReki = (ArrayList<BadugiKarta>) karty.clone();

        BadugiKarta pierwsza = kopiaReki.get(0);
        BadugiKarta ostatnia = kopiaReki.get(3);

        return (Math.abs((ostatnia.figura.getValue() - pierwsza.figura.getValue())) == 4) && !czyPair();
		
	}
	
	private boolean czyColour()
	{
		ArrayList<BadugiKarta> kopiaReki = (ArrayList<BadugiKarta>) karty.clone();
        boolean takieSameKolory = true;
        BadugiKarta pierwsza = kopiaReki.remove(0);

        for (BadugiKarta karta : kopiaReki)
        {
            if ( !karta.kolor.equals(pierwsza.kolor))
            {
                takieSameKolory = false;
                break;
            }

        }

        return takieSameKolory;
		
	}
	
	private boolean porownajFiguryKart(int indeksPierwszej, int indeksDrugiej)
    {
        return  karty.get(indeksPierwszej).figura.equals(karty.get(indeksDrugiej).figura);
    }
	
	private ArrayList<BadugiKarta> zwrocUkladThree()
    {
        ArrayList<BadugiKarta> uklad = new ArrayList<>();

        if (porownajFiguryKart(0, 2))
        {
            uklad.add(karty.get(0));
            uklad.add(karty.get(1));
            uklad.add(karty.get(2));
        }
        else if (porownajFiguryKart(1, 3))
        {
            uklad.add(karty.get(1));
            uklad.add(karty.get(2));
            uklad.add(karty.get(3));
        }
        
        return uklad;
    }
	
	private ArrayList<BadugiKarta> zwrocUkladTwoPairs()
    {

        ArrayList<BadugiKarta> uklad = new ArrayList<>();
        if (porownajFiguryKart(0, 1) && porownajFiguryKart(2, 3))
        {
            @SuppressWarnings("unchecked")
			ArrayList<BadugiKarta> kopiaKarty = (ArrayList<BadugiKarta>)karty.clone();
            uklad.addAll(kopiaKarty);
            uklad.remove(4);
        }
        
        return uklad;
    }
	
	private ArrayList<BadugiKarta> zwrocUkladPair()
    {
        ArrayList<BadugiKarta> uklad = new ArrayList<>();


        if (porownajFiguryKart(0, 1))
        {
            uklad.add(karty.get(0));
            uklad.add(karty.get(1));
        }
        else if (porownajFiguryKart(1, 2))
        {
            uklad.add(karty.get(1));
            uklad.add(karty.get(2));
        }
        else if ( porownajFiguryKart(2, 3))
        {
            uklad.add(karty.get(2));
            uklad.add(karty.get(3));
        }
        
        return uklad;
    }
	
	private int sumaReki()
    {
        return sumaKart(karty);
    }
	
	private int sumaKart(ArrayList<BadugiKarta> karty)
    {
        int suma = 0;
        for (BadugiKarta k : karty)
        {
            suma += k.figura.ordinal();
        }
        return suma;
    }
	
	public int compareTo(BadugiReka drugaReka)
	{
		ustalUklad();
		drugaReka.ustalUklad();
		int wynikPorownania = 0;
		
		
		if (uklad.compareTo(drugaReka.uklad) == 0)
        {
			if (uklad.equals(BadugiUklad.FourCardBadugi))
            {
                
            }
            else if (uklad.equals(BadugiUklad.ThreeCardBadugi))
            {
                
            }
            else if (uklad.equals(BadugiUklad.Pair))
            {
            	wynikPorownania = zwrocUkladPair().get(0).compareTo(drugaReka.zwrocUkladPair().get(0));
                if (wynikPorownania == 0)
                {
                    wynikPorownania = karty.get(3).compareTo(drugaReka.karty.get(3));
                }
            }
            else if (uklad.equals(BadugiUklad.TwoCardBadugi))
            {
                
            }
            else if (uklad.equals(BadugiUklad.TwoPairs))
            {
            	if (sumaKart(zwrocUkladTwoPairs()) == drugaReka.sumaKart(drugaReka.zwrocUkladTwoPairs()))
                {
                    ArrayList<BadugiKarta> kopiaKart = (ArrayList<BadugiKarta>)karty.clone();
                    kopiaKart.removeAll(zwrocUkladTwoPairs());

                    ArrayList<BadugiKarta> kopiaKartDrugaReka = (ArrayList<BadugiKarta>)drugaReka.karty.clone();
                    kopiaKartDrugaReka.removeAll(drugaReka.zwrocUkladTwoPairs());
                    wynikPorownania = kopiaKart.get(0).compareTo(kopiaKartDrugaReka.get(0));
                }
            }
            else if (uklad.equals(BadugiUklad.Three))
            {
            	 wynikPorownania = zwrocUkladThree().get(0).compareTo(drugaReka.zwrocUkladThree().get(0));
            }
            else if (uklad.equals(BadugiUklad.Street))
            {
            	wynikPorownania = karty.get(0).compareTo(drugaReka.karty.get(0));
            }
            else if (uklad.equals(BadugiUklad.Colour))
            {
            	if (sumaReki() > drugaReka.sumaReki())
                {
                    wynikPorownania = 1;
                }
                else
                {
                    wynikPorownania = -1;
                }
            }
            else if (uklad.equals(BadugiUklad.LowestBadugi))
            {
            	wynikPorownania = karty.get(3).compareTo(drugaReka.karty.get(3));
            }
        }
		else
		{
			wynikPorownania = uklad.compareTo(drugaReka.uklad);
		}

		return wynikPorownania;
	}
	
	@Override
    public String toString() {
        return BadugiKarta.pobierzListeKart(karty);
    }
	
}
